from sqlalchemy import event, text

from extension import db, login_manager
from flask_login import UserMixin


class User(UserMixin, db.Model):
    uid = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(150), nullable=False)
    password = db.Column(db.String(150), nullable=False)
    role = db.Column(db.Integer, nullable=False, default=1)
    assigned = db.Column(db.Integer, nullable=False, default=0)
    mail = db.Column(db.String(150), nullable=False)

    def __init__(self, name, password, mail):
        self.name = name
        self.password = password
        self.mail = mail

    def set_password(self, password):
        self.password = password

    def is_admin(self)->bool:
        return self.role == 0

    def get_id(self):
        return self.uid


def set_auto_increment(target, connection, **kw):
    connection.execute(text('ALTER TABLE user AUTO_INCREMENT = 1000'))


event.listen(User.__table__, 'after_create', set_auto_increment)


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))


class Crash(db.Model):
    time = db.Column(db.DateTime, primary_key=True, nullable=False)
    region = db.Column(db.JSON, nullable=False)
    result = db.Column(db.JSON, nullable=False)

    def __init__(self, time, region, result):
        self.time = time
        self.region = region
        self.result = result


class Task(db.Model):
    tid = db.Column(db.Integer, primary_key=True, autoincrement=True)
    placex = db.Column(db.Float, nullable=False)
    placey = db.Column(db.Float, nullable=False)
    finished = db.Column(db.Boolean, nullable=False, default=False)
    starttime = db.Column(db.DateTime, nullable=False)
    endtime = db.Column(db.DateTime, nullable=True)

    def __init__(self, placex,placey, starttime, finished, endtime=None):
        self.placex = placex
        self.placey=placey
        self.starttime = starttime
        self.finished = finished
        self.endtime = endtime

    def set_endtime(self, endtime):
        self.endtime = endtime

    def __repr__(self):
        return f"<Task(tid={self.tid}, placex={self.placex},placey={self.placey}, finished={self.finished}, starttime={self.starttime}, endtime={self.endtime})>"


class Report(db.Model):
    rid = db.Column(db.Integer, primary_key=True, autoincrement=True)
    uid = db.Column(db.Integer, db.ForeignKey('user.uid'), nullable=False)
    tid = db.Column(db.Integer, db.ForeignKey('task.tid'), nullable=False)
    filepath = db.Column(db.String(150), nullable=False)
    title = db.Column(db.String(150), nullable=False)

    def __init__(self, title, filepath, user_id, task_id):
        self.title = title
        self.filepath = filepath
        self.uid = user_id
        self.tid = task_id


class Assignment(db.Model):
    uid = db.Column(db.Integer, db.ForeignKey('user.uid'), primary_key=True, autoincrement=True)
    tid = db.Column(db.Integer, db.ForeignKey('task.tid'), primary_key=True, nullable=False)
    confirmed = db.Column(db.Boolean, nullable=False, default=False)

    def __init__(self, uid, tid, confirmed):
        self.uid = uid
        self.tid = tid
        self.confirmed = confirmed

    def set_confirmed(self, confirmed):
        self.confirmed = confirmed

    def get_confirmed(self):
        return self.confirmed
